package com.ferry.common.util.concurrent;

import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 * Created by daiyong
 * 使用unsafe构造原子更新器 抛弃反射的方式
 */
public class UnsafeAtomicReferenceFieldUpdater<U, W> extends AtomicReferenceFieldUpdater<U, W> {

	private Unsafe unsafe;
	private long offset;

	public UnsafeAtomicReferenceFieldUpdater(Unsafe unsafe, Class<U> tClass, String fieldName) throws NoSuchFieldException {
		Field declaredField = tClass.getDeclaredField(fieldName);
		this.unsafe = unsafe;
		this.offset = unsafe.objectFieldOffset(declaredField);
	}

	@Override
	public boolean compareAndSet(@NotNull U obj, W expect, W update) {
		return unsafe.compareAndSwapObject(obj, offset, expect, update);
	}

	@Override
	public boolean weakCompareAndSet(@NotNull U obj, W expect, W update) {
		return unsafe.compareAndSwapObject(obj, offset, expect, update);
	}

	@Override
	public void set(@NotNull U obj, W newValue) {
		unsafe.putObjectVolatile(obj, offset, newValue);
	}

	@Override
	public void lazySet(@NotNull U obj, W newValue) {
		unsafe.putOrderedObject(obj, offset, newValue);
	}

	@Override
	public W get(@NotNull U obj) {
		return (W) unsafe.getObjectVolatile(obj, offset);
	}
}
